#ifndef NETWORK_H
#define NETWORK_H
#include <map>
#include <vector>
#include <string>
#include <iostream>
#include <cstdio>
#include "swarmSocketServer.h"
#include "swarmSocketClient.h"
#include "robotFunctions.h"
using namespace std;
//! A class to house and control the pieces of a network only have one in operation at a time
class Network
{
	private:
		//! ips holds the IPs of the clients
		map<int, string> ips;
		//! passes holds the passwords of the clients
		map<int, string> passes;
		//! clients holds the swarmSocketClients of the network
		map<int, swarmSocketClient> clients;
		//! cons holds the connection status of the clients
		map<int, bool> cons;
		/*! robot address is the path where the network will look for IPs
		 * if blank, the Network will only use the IPs already in ips
		 */ 
        //string robotaddress;
		//! a buffer to hold incoming messages
		vector<vector<string> > ms;
		//! the listening server
		swarmSocketServer server;
		//! the ID of the network, indicating which IP belongs to the local network's environment
		int botnum;
	public:
		//! uses a default path to look for IPS
		Network();
        // ! \param fileName sets robotaddress
        //Network(string fileName);
		//! \ipList a list of IPs to populate ips
		Network(vector<string> ipList);
		//! initializes the sockets
		void init();
		/*! will wait until host contacts the local Network giving the Local Networks its botnum
		 * /param prefix sets the prefix the Network will look for in initial message from the host
		 */
        void waitForHost(string idPrefix, string ipPrefix, string ipSizePrefix);
		/*! will contact the other Networks in the network, giving them their botnums and telling them who is host
		 * /param prefix sets the prefix the Network prepend to the botnums it sends to the other networks
		 */
        void youAreHost(string idPrefix, string ipPrefix, string ipSizePrefix);
		//! sends a message to all of the clients
		void broadcast(string mess);
		/*! writes a message to a client
		 * \param bot is the botnum which selects the client
		 * \param mess is the message sent to the client
		 * \return 0 if no errors in transmission and < 0 if there was an error
		 */
		int writeMessage(int bot, string mess);
		/*! writes a message to a client
		 * \param ip is the IP which selects the client
		 * \param mess is the message sent to the client
		 * \return 0 if no errors in transmission and < 0 if there was an error
		 */
		int writeMessage(string ip, string message);
		/*! reads messages from a client
		 * \param sec is the number of seconds before timeout, holds if negative
		 * \param mess is the number of microsecond before timeout
		 * \return the messages in the receiving buffer
		 */
		vector<vector<string> > receiveMessage(int sec = 0, int usec = 0);
		/*! checks if a client is connected
		 * \param bot is the botnum which selects the client
		 * \return true if connected false if not connected
		 */
		bool isConnected(int bot);
		/*! refreshed the Networks client connection status and tryes to connect to unconnected clients
		 * \param mess is the message to try to send to unconnected clients
		 * \return true if there was a change in the Network connection status
		 */
        bool refresh(string idPrefix);
		//! \return ms
		vector<vector<string> > getMS();
		//! \return botnum
		int getID();
		//! \return number of clients
		int size();
		//! \return local Network IP
		string getIP();
		/*! \param ID is the botnum which selects the client
		 * \return the IP of the selected Client
		 */
		string getIP(int ID);
	private:
		//! Makes sure the Network cannot be coppied	
		Network(const Network& that);
		//! Makes sure the Network cannot be assigned
		Network& operator=(const Network& that);
};
#endif
